{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "identified-suicide",
   "metadata": {},
   "source": [
    "# Problem 14.02 Work and Temperature Change Upon Isentropic Compression of Oxygen"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "acknowledged-stamp",
   "metadata": {},
   "source": [
    "A stream of gaseous oxygen is compressed from 1 bar to 10 bar. The inlet temperature is 25 °C.\n",
    "Calculate the specific work and the temperature of the outlet gas if the process as an isentropic efficiency of 1, using both the ideal gas law and the SRK equation of state."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "affecting-cloud",
   "metadata": {},
   "source": [
    "## Solution\n",
    "\n",
    "This requires a PT and then a PS flash only. This problem is also good for contrasting simple engineering formulas for compression vs. rigorous thermodynamics."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "selected-volunteer",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Set the conditions and imports\n",
    "from scipy.constants import bar, hour\n",
    "from thermo import ChemicalConstantsPackage, SRKMIX, IdealGas, CEOSLiquid, CEOSGas, FlashPureVLS\n",
    "fluid = 'oxygen'\n",
    "constants, correlations = ChemicalConstantsPackage.from_IDs([fluid])\n",
    "\n",
    "T1 = 298.15\n",
    "P1 = 1*bar\n",
    "P2 = 10*bar"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "short-today",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "With the ideal-gas EOS:\n",
      "The actual power is 7991.3774 J/mol\n",
      "The actual outlet temperature is  560.72 K\n"
     ]
    }
   ],
   "source": [
    "# Use the Ideal-Gas EOS\n",
    "gas = IdealGas(HeatCapacityGases=correlations.HeatCapacityGases)\n",
    "# Note that we can set-up a flasher object with only a gas phase\n",
    "# This obviously has much more performance!\n",
    "flasher = FlashPureVLS(constants, correlations, gas=gas, liquids=[], solids=[])\n",
    "\n",
    "# Flash at inlet conditions to obtain initial enthalpy\n",
    "state_1 = state_1_ideal = flasher.flash(T=T1, P=P1)\n",
    "# Flash at outlet condition - entropy is conserved by compressors and expanders!\n",
    "state_2 = state_2_ideal = flasher.flash(S=state_1.S(), P=P2)\n",
    "\n",
    "actual_power = (state_2.H() - state_1.H()) # W/mol\n",
    "print('With the ideal-gas EOS:')\n",
    "print(f'The actual power is {actual_power:.4f} J/mol')\n",
    "print(f'The actual outlet temperature is {state_2.T: .2f} K')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "utility-annual",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "With the SRK EOS:\n",
      "The actual power is 8000.3185 J/mol\n",
      "The actual outlet temperature is  561.08 K\n"
     ]
    }
   ],
   "source": [
    "# SRK\n",
    "eos_kwargs = dict(Tcs=constants.Tcs, Pcs=constants.Pcs, omegas=constants.omegas)\n",
    "liquid = CEOSLiquid(SRKMIX, HeatCapacityGases=correlations.HeatCapacityGases, eos_kwargs=eos_kwargs)\n",
    "gas = CEOSGas(SRKMIX, HeatCapacityGases=correlations.HeatCapacityGases, eos_kwargs=eos_kwargs)\n",
    "flasher = FlashPureVLS(constants, correlations, gas=gas, liquids=[liquid], solids=[])\n",
    "\n",
    "# Flash at inlet conditions to obtain initial enthalpy\n",
    "state_1 = flasher.flash(T=T1, P=P1)\n",
    "# Flash at outlet condition - entropy is conserved by compressors and expanders!\n",
    "state_2 = state_2_ideal = flasher.flash(S=state_1.S(), P=P2)\n",
    "\n",
    "actual_power = (state_2.H() - state_1.H()) # W/mol\n",
    "print('With the SRK EOS:')\n",
    "print(f'The actual power is {actual_power:.4f} J/mol')\n",
    "print(f'The actual outlet temperature is {state_2.T: .2f} K')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "metric-retrieval",
   "metadata": {},
   "source": [
    "These calculations make use of the full power of the Thermo engine. It is also possible to use simpler calculations to calculate, as shown below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "integral-playback",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using the ideal isentropic exponent 1.395\n",
      "Using the ideal compressibility 1.000\n",
      "The simple power is 8047.5136 J/mol\n",
      "The simple outlet temperature is  572.10 K\n"
     ]
    }
   ],
   "source": [
    "from fluids import isentropic_work_compression, isentropic_T_rise_compression\n",
    "k = state_1_ideal.isentropic_exponent()\n",
    "Z = state_1_ideal.Z()\n",
    "print(f'Using the ideal isentropic exponent {k:.3f}')\n",
    "print(f'Using the ideal compressibility {Z:.3f}')\n",
    "molar_work = isentropic_work_compression(T1=T1, k=state_1_ideal.isentropic_exponent(), Z=state_1_ideal.Z(), P1=P1, P2=P2, eta=1)\n",
    "T2 = isentropic_T_rise_compression(T1=T1, P1=P1, P2=P2, k=k, eta=1)\n",
    "print(f'The simple power is {molar_work:.4f} J/mol')\n",
    "print(f'The simple outlet temperature is {T2: .2f} K')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "starting-sucking",
   "metadata": {},
   "source": [
    "From these results, we can see that for small pressure increases, the ideal-gas and SRK equations work quite similarly. There is also a very large difference in outlet temperature between the simplified equations given in many textbooks, and the real isentropic calculations when a temperature-dependent heat capacity is used. Therefore, there are substantial advantages to rigorous modeling, regardless of the complexity of the EOS for the gas phase."
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
